package com.xexun.gpstracker.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class DigestUtils {
    public static List<String> termKeysList = new ArrayList<>();
    public static List<String> appKeysList = new ArrayList<>();

//    static {
//        String termKeys = System.getProperty("protocal.termkeys");
//        String appKeys = System.getProperty("protocal.appkeys");
//        String[] termKeyArr = termKeys.split(",");
//        String[] appKeyArr = appKeys.split(",");
//        termKeysList = Arrays.asList(termKeyArr);
//        appKeysList = Arrays.asList(appKeyArr);
//    }

    public static void main(String[] args) throws IOException {//5678EUFBIVK   EGEPUBTT
//        List<Integer> keys = genarateTermKey();
        String str = "477,269,247,454,243,177,176,382,432,242,357,497,263,361,220,106,276,350,113,108,194,306,443,303,471,268,330,404,458,110,317,167,261,179,112,400,405,375,242,118,446,323,468,273,380,451,414,298,308,182,219,305,185,450,261,491,394,273,348,278,456,124,367,298,438,322,157,189,457,101,325,387,127,289,473,129,283,313,145,284,286,161,236,371,419,354,209,310,145,221";
        String[] stra = str.split(",");
        List<Integer> keys = new ArrayList<>();
        List<String> keyss = Arrays.asList(stra);
        keys.add(497);
        keys.add(283);
        keys.add(438);
        String encrypt = encrypt("xexun", keys);//568959DVDC?*A=?(
        System.err.println(StringCoder.bytesToHexString(encrypt.getBytes("UTF-8"), "-"));
        System.err.println(/*StringCoder.fillZeroLeft(String.valueOf(keys.get(3)),2)
                +StringCoder.fillZeroLeft(String.valueOf(keys.get(4)),2)
                +StringCoder.fillZeroLeft(String.valueOf(keys.get(5)),2)+*/new String(encrypt.getBytes("utf-8"), "utf-8"));
        System.err.println(decrypt(encrypt, keys));
        System.err.println(decrypt("DVDC?*A=?(", keys));

    }

    public static List<Integer> genarateTermKey() {
        int termSize = termKeysList.size();
        Random random = new Random();
        int termRandom1 = random.nextInt(termSize);
        int termRandom2 = random.nextInt(termSize);
        int termRandom3 = random.nextInt(termSize);
        int TERM_KEY_X = Integer.parseInt(termKeysList.get(termRandom1));
        int TERM_KEY_Y = Integer.parseInt(termKeysList.get(termRandom2));
        int TERM_KEY_Z = Integer.parseInt(termKeysList.get(termRandom3));
        List<Integer> termKeyList = new ArrayList<>();
        termKeyList.add(TERM_KEY_X);
        termKeyList.add(TERM_KEY_Y);
        termKeyList.add(TERM_KEY_Z);
        termKeyList.add(termRandom1);
        termKeyList.add(termRandom2);
        termKeyList.add(termRandom3);
        return termKeyList;
    }

    public static List<Integer> genarateAppKey() {
        int appSize = appKeysList.size();
        Random random = new Random();
        int appRandom1 = random.nextInt(appSize);
        int appRandom2 = random.nextInt(appSize);
        int appRandom3 = random.nextInt(appSize);
        int APP_KEY_X = Integer.parseInt(appKeysList.get(appRandom1));
        int APP_KEY_Y = Integer.parseInt(appKeysList.get(appRandom2));
        int APP_KEY_Z = Integer.parseInt(appKeysList.get(appRandom3));
        List<Integer> appKeyList = new ArrayList<>();
        appKeyList.add(APP_KEY_X);
        appKeyList.add(APP_KEY_Y);
        appKeyList.add(APP_KEY_Z);
        appKeyList.add(appRandom1);
        appKeyList.add(appRandom2);
        appKeyList.add(appRandom3);
        return appKeyList;
    }

    public static List<Integer> getTermKeyByNum(String str) {
        if (!CommUtil.isBlank(str) &&
                str.length() >= 6) {
            int num = Integer.parseInt(str.substring(0, 6));
            int bai = num / 10000;
            int shi = num / 100 - bai * 100;
            int ge = num - bai * 10000 - shi * 100;
            int TERM_KEY_X = Integer.parseInt(termKeysList.get(bai));
            int TERM_KEY_Y = Integer.parseInt(termKeysList.get(shi));
            int TERM_KEY_Z = Integer.parseInt(termKeysList.get(ge));
            List<Integer> appKeyList = new ArrayList<>();
            appKeyList.add(TERM_KEY_X);
            appKeyList.add(TERM_KEY_Y);
            appKeyList.add(TERM_KEY_Z);
            return appKeyList;
        }
        return null;
    }

    public static List<Integer> getAppKeyByNum(String str) {
        if (!CommUtil.isBlank(str) &&
                str.length() >= 6) {
            int num = Integer.parseInt(str.substring(0, 6));
            int bai = num / 10000;
            int shi = num / 100 - bai * 100;
            int ge = num - bai * 10000 - shi * 100;
            int APP_KEY_X = Integer.parseInt(appKeysList.get(bai));
            int APP_KEY_Y = Integer.parseInt(appKeysList.get(shi));
            int APP_KEY_Z = Integer.parseInt(appKeysList.get(ge));
            List<Integer> appKeyList = new ArrayList<>();
            appKeyList.add(APP_KEY_X);
            appKeyList.add(APP_KEY_Y);
            appKeyList.add(APP_KEY_Z);
            return appKeyList;
        }
        return null;
    }

    public static String encrypt(String str, List<Integer> keys) {
        int keyx = keys.get(0);
        int keyy = keys.get(1);
        int keyz = keys.get(2);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            byte chs = (byte) (ch ^ (keyx >>> 8));
            sb.append((char) chs);
            keyx = ((byte) sb.charAt(i) + keyx) * keyy + keyz;
        }
        str = sb.toString();
        sb.delete(0, sb.length());
        for (int i = 0; i < str.length(); i++) {
            byte temp = (byte) str.charAt(i);
            String res = String.valueOf((char) (byte) (65 + temp / 26));
            res += ((char) (65 + temp % 26));
            sb.append(res);
        }
        return sb.toString();
    }

    public static String decrypt(String str, List<Integer> keys) {
        int keyx = keys.get(0);
        int keyy = keys.get(1);
        int keyz = keys.get(2);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length() / 2; i++) {
            int temp = ((int) (str.charAt(2 * i)) - 65) * 26;
            temp += (int) str.charAt(2 * i + 1) - 65;
            String res = String.valueOf((char) (byte) temp);
            sb.append(res);
        }

        str = sb.toString();
        sb.delete(0, sb.length());

        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            sb.append((char) (byte) (ch ^ (keyx >>> 8)));
            keyx = ((byte) ch + keyx) * keyy + keyz;
        }
        return sb.toString();
    }
}
